home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / RTVBE210.ZIP / _VESA2.C < prev    next >
C/C++ Source or Header  |  1997-01-06  |  9KB  |  349 lines

  1. ;/************************************************************************
  2. ; *
  3. ; *     File        :   _VESA.C
  4. ; *
  5. ; *     Description :   VBE-2.00 Interface
  6. ; *
  7. ; *     Copyright (C) 1994,96 Realtech
  8. ; *
  9. ; ***********************************************************************/
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <dos.h>
  13. #include "_standar.h"
  14. #include "_vesa.h"
  15. #include "_wdpmi.h"
  16. #include "_dpmi.h"
  17.  
  18. VesaInfoBlock vesabuf;
  19. VesaModeInfo modebuf;
  20. VesaSystem VESA;
  21. /*------------------------------------------------------------------------
  22. *
  23. * PROTOTYPE  : void FAR48 *VBE_get_ptr_to_LFB(long physaddr)
  24. *
  25. * DESCRIPTION : Recupere l'adresse à remapper
  26. *
  27. */
  28. #define LIMIT4G 4096L*1024L-1L
  29. ulong  VESA_linAddr = 0;
  30. ushort VESA_selAddr = 0;
  31. void FAR48 *VBE_get_LFB(long physaddr,short *selector)
  32. {
  33.     __dpmi_meminfo info;
  34.     if (VESA_linAddr)
  35.     {
  36.     info.address = VESA_linAddr;
  37.     __dpmi_free_physical_address_mapping(&info);
  38.     VESA_linAddr = 0;
  39.     }
  40.     if (VESA_selAddr)
  41.     {
  42.        __dpmi_free_ldt_descriptor(VESA_selAddr);
  43.     VESA_selAddr = 0;
  44.     }
  45.     VESA_selAddr = __dpmi_allocate_ldt_descriptors(1);
  46.     if (__dpmi_set_descriptor_access_rights(VESA_selAddr,0x8092)) error("PM right failed",8);
  47.     info.address = physaddr;
  48.     info.size    = LIMIT4G;
  49.     if (!__dpmi_physical_address_mapping(&info)) // carry clear
  50.     {
  51.        VESA_linAddr = info.handle;
  52.        __dpmi_set_segment_base_address(VESA_selAddr,VESA_linAddr);
  53.        __dpmi_set_segment_limit(VESA_selAddr,LIMIT4G);
  54.        __dpmi_get_segment_base_address(VESA_selAddr,&VESA_linAddr);
  55.        #ifdef USE_VESAFAR
  56.        VESA.Video = NULL;
  57.        #else
  58.        VESA.Video = (uchar*)VESA_linAddr; //<<= Pointer to Video
  59.        #endif
  60.        VESA.Linear = 1;
  61.        *selector = (short)VESA_selAddr;
  62.        #ifdef __WATCOM__
  63.        return MK_FP(VESA_selAddr,0);
  64.        #else
  65.        return (void FAR48*)VESA_selAddr; //GNU C
  66.        #endif
  67.     }
  68.     error("Cannot remap address",info.address);
  69.     *selector   = 0;
  70.     VESA.Linear = 0;
  71.     return NULL;
  72. }
  73.  
  74. /*------------------------------------------------------------------------
  75. *
  76. * PROTOTYPE  : int VBE_get_infos(int VESAmode)
  77. *
  78. * DESCRIPTION : Detecte si le mode est supporté par le BIOS
  79. *
  80. */
  81. int VBE_get_infos(int VESAmode)
  82. {
  83.     __dpmi_regs regs;
  84.     regs.x.ax = 0x4F01;
  85.     regs.x.cx = VESAmode;
  86.     regs.x.di = 0;
  87.     memset(&modebuf,0,sizeof(VesaModeInfo));
  88.     PM_callES(0x10,®s, &modebuf, sizeof(VesaModeInfo));
  89.     return (regs.x.ax == 0x004F);
  90. }
  91. /*------------------------------------------------------------------------
  92. *
  93. * PROTOTYPE  : int Get_ModeByInfo(int width,int height,int bbp)
  94. *
  95. * DESCRIPTION : Recherche le numero de mode selon la taille de l'ecran desiré
  96. *
  97. */
  98. int VBE_get_mode_by_infos(int width,int height,int bbp)
  99. {
  100.    int i;
  101.    for (i=0x100;i<=0x200;i++)
  102.    {
  103.       if (VBE_get_infos(i))
  104.        {
  105.       if  ((modebuf.XResolution==width)
  106.         &&(modebuf.YResolution==height)
  107.         &&(modebuf.BitsPerPixel==bbp))
  108.          {
  109.            return i;
  110.          }
  111.        }
  112.    }
  113.    memset(&modebuf,0,sizeof(VesaModeInfo));
  114.    return 0;
  115. }
  116. /*------------------------------------------------------------------------
  117. *
  118. * PROTOTYPE  : int VBE_get_OEM_infos(void)
  119. *
  120. * DESCRIPTION : Detecte si y a un BIOS VESA
  121. *               Essaye ensuite d'initialiser le mode en lineaire
  122. *
  123. */
  124. int VBE_get_OEM_infos(void)
  125. {
  126.     __dpmi_regs regs;
  127.     memset(&vesabuf,0,sizeof(VesaInfoBlock));
  128.     strncpy(vesabuf.VESASignature,"VBE2",4);
  129.     /* Get SuperVGA information */
  130.     regs.x.ax = 0x4F00;
  131.     regs.x.di = 0;
  132.     PM_callES(0x10,®s, &vesabuf, sizeof(VesaInfoBlock));
  133.     if (regs.x.ax != 0x004F) return 0;
  134.     if (strncmp(vesabuf.VESASignature,"VESA",4) != 0)
  135.     {
  136.     memset(&vesabuf,0,sizeof(VesaInfoBlock));
  137.     VESA.Linear = 2;
  138.     return 0;
  139.     }
  140.     VESA.CardName  = (char*)PHYSIC_ADRESS(vesabuf.OEMStringPtr);
  141.     return 1;
  142. }
  143. int VBE_set_mode(int mode)
  144. {
  145.     __dpmi_regs regs;
  146.     regs.x.ax = 0x4F02;
  147.     regs.x.bx = mode;
  148.     __dpmi_int(0x10,®s);
  149.     if (regs.x.ax==0x004f)
  150.     {
  151.       // Some video card (like Matrox Millenium in 800x600)
  152.       // set a wrong scanline length . So we fix it !)
  153.       VBE_set_scanline_length(modebuf.XResolution);
  154.       return 1;
  155.     }
  156.     return 0;
  157. }
  158. #define vbeMemPK       4
  159. #define vbeUseLFB      0x4000
  160. #define vbeMdAvailable 0x0001
  161. #define vbeMdColorMode 0x0008
  162. #define vbeMdGraphMode 0x0010
  163. #define vbeMdNonbanked 0x0040
  164. #define vbeMdLinear    0x0080
  165. int VBE_get_LFB_infos(void)
  166. {
  167.     VESA.bankshift   = 0;
  168.     VESA.Linear      = 0;
  169.     VESA.LFB_actived = 0;
  170.  
  171.     if ((modebuf.ModeAttributes & vbeMdAvailable)
  172.       &&(modebuf.ModeAttributes & vbeMdLinear))
  173.     {
  174.     VBE_get_LFB(modebuf.PhysBasePtr,&VESA.selector);
  175.     VESA.LFB_actived = VESA.Linear;
  176.     }
  177.     if (!VESA.Linear)
  178.     {
  179.     while ((64>>VESA.bankshift)!=modebuf.WinGranularity) VESA.bankshift++;
  180.     }
  181.     return 1;
  182. }
  183. int VBE_set_gfx_mode(int VESAmode)
  184. {
  185.     if (VESAmode<0x100) error("Impossible",VESAmode);
  186.     return VBE_set_mode( VESA.LFB_actived ? VESAmode | vbeUseLFB : VESAmode);
  187. }
  188.  
  189. int VBE_set_vesa_mode(int VESAmode)
  190. {
  191.     if (!VBE_get_infos(VESAmode)) return 0;
  192.     VBE_get_LFB_infos();
  193.     return VBE_set_gfx_mode(VESAmode) ? vesabuf.VESAVersion : 0;
  194. }
  195. /*------------------------------------------------------------------------
  196. *
  197. * PROTOTYPE  : bool set8BitPalette(void)
  198. *
  199. * DESCRIPTION : y a-t-il un DAC etendu 8Bit ?
  200. *
  201. */
  202. bool VBE_set8BitPalette(void)
  203. {
  204.     __dpmi_regs  regs;
  205.     regs.x.ax = 0x4F08;         /* Set DAC service                      */
  206.     regs.x.bx = 0x0800;         /* BH := 8, BL := 0 (set DAC width)     */
  207.     __dpmi_int(0x10,®s);
  208.     if (regs.x.ax != 0x004F)
  209.     return false;           /* Function failed, no wide dac         */
  210.     if (regs.h.bh == 6)
  211.     return false;
  212.     regs.x.ax = 0x4F08;
  213.     regs.x.bx = 0x0001;         /* Get DAC width (should now be 8)      */
  214.     __dpmi_int(0x10,®s);
  215.     if (regs.x.ax != 0x004F)
  216.     return false;
  217.     if (regs.h.bh != 8)
  218.     return false;
  219.     return true;
  220. }
  221. /*------------------------------------------------------------------------
  222. *
  223. * PROTOTYPE  : bool set6BitPalette(void)
  224. *
  225. * DESCRIPTION : y a-t-il un DAC etendu 6Bit ?
  226. *
  227. */
  228. bool VBE_set6BitPalette(void)
  229. {
  230.     __dpmi_regs  regs;
  231.     regs.x.ax = 0x4F08;
  232.     regs.x.bx = 0x0600;
  233.     __dpmi_int(0x10,®s);     /* Restore to 6 bit DAC               */
  234.     if (regs.x.ax != 0x004F)
  235.     return true;
  236.     if (regs.h.bh != 6)
  237.     return false;
  238.     return true;
  239. }
  240. /*------------------------------------------------------------------------
  241. *
  242. * PROTOTYPE  : void CALLING_C setVESAPalette(ulong a, ulong b, void * pal)
  243. *
  244. * DESCRIPTION : Change 'b' couleurs à partir de 'a' avec la table 'pal'
  245. *
  246. */
  247.  
  248. void CALLING_C VBE_set_palette(ulong a, ulong b, void * pal)
  249. {
  250.     __dpmi_regs  regs;
  251.     regs.x.ax = 0x1012;
  252.     regs.x.bx = a;
  253.     regs.x.cx = b;
  254.     regs.x.es = PMB.rseg;
  255.     regs.x.dx = PMB.roff;
  256.     PM_memcpyfn(PMB.sel,PMB.off, pal, (b-1) * 3);
  257.     //WaitSynchro();
  258.     __dpmi_int(0x10, ®s);
  259.     return;
  260. }
  261. /*------------------------------------------------------------------------
  262. *
  263. * PROTOTYPE  : void getVESAPalette(int start, int num, uchar *palbuf)
  264. *
  265. * DESCRIPTION : recupere la palette en cours
  266. *
  267. */
  268. void VBE_get_palette(int start, int num, uchar *palbuf)
  269. {
  270.     __dpmi_regs  regs;
  271.     regs.x.ax = 0x1017;
  272.     regs.x.bx = start;
  273.     regs.x.cx = num;
  274.     regs.x.es = PMB.rseg;
  275.     regs.x.dx = PMB.roff;
  276.     __dpmi_int(0x10, ®s);
  277.     PM_memcpynf(palbuf, PMB.sel,PMB.off, num * 3);
  278.     return;
  279. }
  280. /*------------------------------------------------------------------------
  281. *
  282. * PROTOTYPE  :  BITBLT_xflip
  283. *
  284. * DESCRIPTION : Double Flipping en mode VESA 2.00
  285. *
  286. */
  287. void CALLING_C BITBLT_xflipVESA(void)
  288. {
  289.     /*
  290.     __dpmi_regs  regs;
  291.     ulong x;
  292.     VESA.offset = GXView.Page ? modebuf.YResolution : 0;
  293.     x = (ulong)VESA.offset * (ulong)modebuf.BytesPerLine;
  294.     GXView.video   = GXView.ptr;
  295.     GXView.ptr = VESA.Video + x;
  296.     GXView.Page^=1;
  297.     regs.x.ax = 0x4F07;
  298.     regs.x.bx = 0x0000;    //00h:set 01h:get 80h:during Vertical
  299.     regs.x.cx = 0;
  300.     regs.x.dx = GXView.Page ? modebuf.YResolution : 0;
  301.     __dpmi_int(0x10,®s);
  302.     WaitSynchro();
  303.     */
  304.     return;
  305. }
  306. /*------------------------------------------------------------------------
  307. *
  308. * PROTOTYPE  : void VESASetScanLineLength(long newcx)
  309. *
  310. * DESCRIPTION : Change le scanline (en bytes)
  311. *
  312. */
  313.  
  314. void VBE_set_scanline_length(long newcx)
  315. {
  316.     __dpmi_regs  regs;
  317.     regs.x.ax = 0x4F06;
  318.     regs.x.bx = 0x0000;     //Set Scanline
  319.     regs.x.cx = newcx;
  320.     regs.x.dx = 0x0000;
  321.     __dpmi_int(0x10,®s);
  322.     if (regs.x.ax!=2)
  323.     {
  324.       regs.x.ax = 0x4F06;
  325.       regs.x.bx = 0x0001;   // Get Scanline
  326.       regs.x.dx = 0x0000;
  327.       __dpmi_int(0x10,®s);
  328.       if (regs.x.bx) modebuf.BytesPerLine = regs.x.bx;
  329.     }
  330.     return;
  331. }
  332. /*------------------------------------------------------------------------
  333. *
  334. * PROTOTYPE  : void VESASetXY (long x,long y)
  335. *
  336. * DESCRIPTION : Change le start adress de la video
  337. *
  338. */
  339. void VBE_set_offset(long x,long y)
  340. {
  341.     __dpmi_regs regs;
  342.     regs.x.ax = 0x4F07;
  343.     regs.x.bx = 0x0000;
  344.     regs.x.cx = x;
  345.     regs.x.dx = y;
  346.     __dpmi_int(0x10,®s);
  347.     return;
  348. }
  349.